import os
import yaml
import logging
from datetime import datetime

class Struct(dict):
    """
    - 功能：为字典加上点语法，实现 对象.属性 调用。
    - 例如:
    >>> d = Struct({'age':18})
    >>> d.age
    >>> 18
    >>> d.gender
    >>> None
    """

    def __init__(self, dictobj={}):
        self.update(dictobj)

    def __getattr__(self, name):
        # Pickle is trying to get state from your object, and dict doesn't implement it.
        # Your __getattr__ is being called with "__getstate__" to find that magic method,
        # and returning None instead of raising AttributeError as it should.
        if name.startswith('__'):
            raise AttributeError
        return self.get(name)

    def __setattr__(self, name, val):
        self[name] = val

    def __hash__(self):
        return id(self)

class Config(Struct):
    def __init__(self, args):
        self.args = args
        self.config = self.updata_config(self.args)

    def updata_config(self, args):
        config = self.load_config_file(args.cfg)
        config['train_flag'] = args.train_flag
        if args.train_flag:
            self.creat_config(config)
        config = self.conver_dict(config)
        return config

    def load_config_file(self, filePath):
        with open(filePath, 'r') as f:
            cont = f.read()
            y = yaml.load(cont)
        return y

    def creat_config(self, config):
        if config['train_flag']:
            outputdir = config['output_root']
            modelName = config['model']['model_name']
            version = config['version']
            output = os.path.join(outputdir, modelName, version)
            if not os.path.exists(output):
                os.makedirs(output)
            log = os.path.join(output, "log")
            if not os.path.exists(log):
                os.makedirs(log)

            config['train']["output_dir"] = output

            da = datetime.now()
            logname = da.strftime('%Y-%m-%d_time_%H_%M_%S') + '.log'
            log_fp = os.path.join(log, logname)
            logging.basicConfig(format='%(asctime)s:%(levelname)s:%(message)s',
                                level=logging.INFO,
                                filename=log_fp,
                                filemode='w')

            console = logging.StreamHandler()
            console.setLevel(logging.INFO)
            logging.getLogger('').addHandler(console)
        else:
            logging.basicConfig(format='%(asctime)s:%(levelname)s:%(message)s', level=logging.INFO)

    def conver_dict(self, config):
        if config['train_flag']:
            train = Struct(config['train'])
        else:
            train = None
        test = Struct(config['test'])
        model = Struct(config['model'])
        label = Struct(config['label'])
        config = Struct(dict(train=train, test=test, model=model, label=label,
                              train_flag=config['train_flag']))
        return config

    def get_config(self):
        return self.config